﻿using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;

namespace AYA.Core.Cache
{
    /// <summary>
    /// 用于管理整个框架的缓存
    /// </summary>
    public class CacheManager
    {
        private readonly Dictionary<string, CacheItem> _items;
        private static CacheManager _current;
        private log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        /// <summary>
        /// 静态构造函数确保这是一个单件
        /// </summary>
        private CacheManager()
        {
            if (_items == null)
                _items = new Dictionary<string, CacheItem>();
        }

        /// <summary>
        /// CacheManager的唯一实例
        /// </summary>
        public static CacheManager Current
        {
            get
            {
                if (_current == null)
                {                   
                    _current = new CacheManager();
                }
                return _current;
            }
        }

        /// <summary>
        /// 清空所有缓存项
        /// </summary>
        public void Clear()
        {
            _current = new CacheManager();
        }

        /// <summary>
        /// 添加到缓存
        /// </summary>
        /// <param name="key">键</param>
        /// <param name="value">值</param>
        /// <param name="expirationSecond">相对过期时间,如果为-1则不过期</param>
        /// <param name="absoluteExpirationSecond">绝对过期时间,如果为-1则不过期</param>
        /// <param name="dependencyFilePath">依赖的文件路径,如果为空则不过期</param>
        public  void Add(string key, object value, int expirationSecond, int absoluteExpirationSecond, string dependencyFilePath)
        {
            if(_items.ContainsKey(key))
                _items[key]=new CacheItem(value,expirationSecond,absoluteExpirationSecond,dependencyFilePath);
            else
                _items.Add(key,new CacheItem(value,expirationSecond,absoluteExpirationSecond,dependencyFilePath));
        }

        /// <summary>
        /// 根据key取出已缓存的值
        /// </summary>
        /// <param name="key">key</param>
        /// <returns></returns>
        public object Get(string key)
        {
            if (_items.ContainsKey(key))
            {
                if (_items[key].IsExpirated)
                {
                    _items[key].Dispose();
                    _items.Remove(key);
                }
                else
                    return _items[key];
            }
            return null;
        }

        /// <summary>
        /// 根据key更新一个已经缓存的项,如果该项不存在则引发异常
        /// </summary>
        /// <param name="key">key</param>
        public void Update(string key,object value)
        {
            if (this._items.ContainsKey(key))
                this._items[key].Value = value;
            else
            {
                log.Error("试图更新一个不存在的缓存项." + key);
                //throw new Exception("试图更新一个不存在的缓存项.");
            }
        }

        /// <summary>
        /// 根据key取得/更新缓存项，试图更新一个不存在的项则引发异常
        /// </summary>
        /// <param name="key">key</param>
        /// <returns></returns>
        public object this[string key]
        {
            get { return Get(key); }
            set { Update(key, value); }
        }

        /// <summary>
        /// 从缓存中移除项
        /// </summary>
        /// <param name="key">要移除的Key</param>
        public void RemoveItem(string key)
        {
            if (_items.ContainsKey(key))
                _items.Remove(key);
        }
        
    }
}
